package com.watson.todolist.database;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.watson.todolist.constants.DatabaseConstants;
import com.watson.todolist.to.TagItem;

/**
 * The tag manager class handles persisting todo items by directly interacting
 * with the database. A TagManager object allows access to get tag item data
 * from the database and to put data inside of the database.
 * 
 * @author Donnie Ward
 * 
 * @since 1.0
 */
public class TagManager {
	/**
	 * Logger tag
	 */
	private static String TAG = "TagManager Class";
	/**
	 * Database instance
	 */
	private SQLiteDatabase db;

	/**
	 * Tag manager construction which initializes the database instance
	 * 
	 * @param db
	 *            - An instance of the database
	 */
	public TagManager(SQLiteDatabase db) {
		this.db = db;
	}

	/**
	 * Creates tag
	 * 
	 * @param userId
	 *            - User's id
	 * @param tagName
	 *            - Tag name
	 * @return tagRowId - the tag ID of the newly inserted row, or -1 if an
	 *         error occurred
	 */
	public long createTag(long userId, String tagName) {
		ContentValues values = createContentValues(userId, tagName);
		return db.insert(DatabaseConstants.TAG_ITEM_TABLE_NAME, null, values);
	}

	/**
	 * Updates tag
	 * 
	 * @param tagId
	 *            - Tag id
	 * @param userId
	 *            - User id
	 * @param tagName
	 *            Tag name
	 * @return successStatus - true if tag updated successful and false
	 *         otherwise
	 */
	public boolean updateTag(long tagId, long userId, String tagName) {
		ContentValues values = createContentValues(userId, tagName);
		return db.update(DatabaseConstants.TAG_ITEM_TABLE_NAME, values,
				DatabaseConstants.ID + "=" + tagId, null) > 0;
	}

	/**
	 * Deletes tag by given tag id
	 * 
	 * @param tagId
	 *            - Tag id
	 * @return successStatus - true if tag updated successful and false
	 *         otherwise
	 */
	public boolean deleteTagByTagId(long tagId) {
		return db.delete(DatabaseConstants.TAG_ITEM_TABLE_NAME,
				DatabaseConstants.ID + "=" + tagId, null) > 0;
	}

	/**
	 * Gets tag by given tag id
	 * 
	 * @param tagId
	 *            - Tag id
	 * @return tagItem - populated tag item if successful and null otherwise
	 */
	public TagItem getTagByTagId(long tagId) {
		Cursor cursor = db.query(true, DatabaseConstants.TAG_ITEM_TABLE_NAME,
				new String[] { DatabaseConstants.ID,
						DatabaseConstants.TIME_STAMP,
						DatabaseConstants.TAG_ITEM_TABLE_USER_ID,
						DatabaseConstants.TAG_ITEM_TABLE_TAG_NAME },
				DatabaseConstants.ID + "=" + tagId, null, null, null, null,
				null);

		// Move cursor to first row
		if (cursor != null) {
			cursor.moveToFirst();
		}

		// Check to see if any rows were returned to cursor
		if (cursor == null || cursor.getCount() == 0) {
			Log.d(TAG, "No rows contained in cursor in getTagByTagId()");
			return null;
		}

		// Populating tag item
		TagItem tagItem = new TagItem();
		tagItem.setTagId(cursor.getLong(cursor
				.getColumnIndex(DatabaseConstants.ID)));
		tagItem.setTagName(cursor.getString(cursor
				.getColumnIndex(DatabaseConstants.TAG_ITEM_TABLE_TAG_NAME)));
		tagItem.setUserId(cursor.getLong(cursor
				.getColumnIndex(DatabaseConstants.TAG_ITEM_TABLE_USER_ID)));

		return tagItem;
	}

	/**
	 * Gets all tags created by user with given user id
	 * 
	 * @param userId
	 *            - User's id
	 * @return listOfTagItems - populated list of populated tag items if
	 *         successful and null otherwise
	 */
	public List<TagItem> getAllTagsByUserId(long userId) {
		Cursor cursor = db.query(true, DatabaseConstants.TAG_ITEM_TABLE_NAME,
				new String[] { DatabaseConstants.ID,
						DatabaseConstants.TIME_STAMP,
						DatabaseConstants.TAG_ITEM_TABLE_USER_ID,
						DatabaseConstants.TAG_ITEM_TABLE_TAG_NAME },
				DatabaseConstants.TAG_ITEM_TABLE_USER_ID + "=" + userId, null,
				null, null, null, null);

		// Move cursor to first row
		if (cursor != null) {
			cursor.moveToFirst();
		}

		// Check to see if any rows were returned to cursor
		if (cursor == null || cursor.getCount() == 0) {
			Log.d(TAG, "No rows contained in cursor in getAllTagsByUserId()");
			return null;
		}

		// Populate tag items and put them in a list
		List<TagItem> tagItemList = new ArrayList<TagItem>();
		while (!cursor.isAfterLast()) {
			TagItem tagItem = new TagItem();
			tagItem.setTagId(cursor.getLong(cursor
					.getColumnIndex(DatabaseConstants.ID)));
			tagItem.setTagName(cursor.getString(cursor
					.getColumnIndex(DatabaseConstants.TAG_ITEM_TABLE_TAG_NAME)));
			tagItem.setUserId(cursor.getLong(cursor
					.getColumnIndex(DatabaseConstants.TAG_ITEM_TABLE_USER_ID)));

			tagItemList.add(tagItem);
			cursor.moveToNext();
		}
		return tagItemList;
	}

	/**
	 * Creates content values
	 * 
	 * @param userId
	 *            - User's id
	 * @param tagName
	 *            - Tag name
	 * @return contentValues - populated content values
	 */
	private ContentValues createContentValues(long userId, String tagName) {
		ContentValues values = new ContentValues();
		values.put(DatabaseConstants.TAG_ITEM_TABLE_USER_ID, userId);
		values.put(DatabaseConstants.TAG_ITEM_TABLE_TAG_NAME, tagName);
		return values;
	}
}
